import backtrader as bt
class MACDGOLDStrategy(bt.Strategy):
    params = (
        ('dif_threshold', -0.4),  # DIF阈值
        ('rsi_period', 14),       # RSI周期
        ('rsi_oversold', 30),     # RSI超卖阈值
    )
    def log(self, txt, dt=None):
        """记录日志"""
        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')
    def __init__(self):
        self.data_close = self.datas[0].close
        self.data_low = self.datas[0].low
        
        # 计算MACD指标 - 修正属性名
        self.macd = bt.indicators.MACD(self.data_close)
        self.dif = self.macd.macd      # MACD线 (DIF)
        self.dea = self.macd.signal    # 信号线 (DEA)
        self.bar = self.macd.macdhist  # 柱状图 (BAR/MACDHIST)
        
        # X_38: MACD即将金叉的条件分析
        # 获取前一天的值
        self.dif_prev = self.dif(-1)
        self.dea_prev = self.dea(-1)
        
        # 条件：DIF正在上升且接近DEA线（即将金叉）
        self.dif_rising = self.dif > self.dif_prev
        self.dif_below_dea = self.dif < self.dea
        self.dif_approaching = (self.dea - self.dif) < abs(self.dif) * 0.2  # 接近程度
        
        self.x_38 = bt.And(self.dif_below_dea, self.dif_rising, self.dif_approaching)
        
        # X_34: 短期超跌条件
        self.rsi = bt.indicators.RSI(self.data_close, period=self.p.rsi_period)
        self.rsi_oversold = self.rsi < self.p.rsi_oversold
        
        # 价格相对位置判断（20日周期）
        self.lowest_20 = bt.indicators.Lowest(self.data_low, period=20)
        self.highest_20 = bt.indicators.Highest(self.data_close, period=20)
        self.price_position = (self.data_close - self.lowest_20) / (self.highest_20 - self.lowest_20 + 0.0001)
        self.price_oversold = self.price_position < 0.3
        
        self.x_34 = bt.And(self.rsi_oversold, self.price_oversold)
        
        # X_49: 综合买入信号
        self.condition1 = self.dif > self.p.dif_threshold  # DIF > -0.4
        self.x_49 = bt.And(self.condition1, self.x_38, self.x_34)
        
        self.order = None
    def next(self):
        if self.order:
            return
            
        # 买入信号检测
        if self.x_49[0]:
            self.log(f'MACD金叉前买入信号触发!')
            self.log(f'DIF: {self.dif[0]:.6f}, DEA: {self.dea[0]:.6f}')
            self.log(f'RSI: {self.rsi[0]:.2f}, 价格位置: {self.price_position[0]:.2f}')
            self.log(f'信号图标位置: {self.data_low[0]*0.97:.2f} (笑脸图标)')
            
            # 执行买入操作
            if not self.position:
                self.log('执行买入操作')
                self.order = self.buy()
            else:
                self.log('已有持仓，跳过买入')
    def notify_order(self, order):
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'买入执行, 价格: {order.executed.price:.2f}, 数量: {order.executed.size}')
            elif order.issell():
                self.log(f'卖出执行, 价格: {order.executed.price:.2f}, 数量: {order.executed.size}')
            self.order = None
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('订单取消/保证金不足/拒绝')
            self.order = None